/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package smartclient.client;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

import javax.crypto.SealedObject;

import smartclient.client.comparators.QuoteSealedComparator;

/**
 *
 * @author Paolo
 */
public class File2Quote {
    //private int index; // indice del chunk corrente.
    private long residuo; // varaibile usata per calcolare il riempimento del file. Succede che fissata una dimensione del pacchetto, l'ultimo pacchetto da trasmettere sia di dimensione inferiore al pacchetto contenitore, quindi lo si deve riempire.


    public FileQuoted fileToQuote(File file){
        FileQuoted fq = new FileQuoted();
        fq.setName(file.getName()); //TODO: controllare funzione NAME nel Worker
        fq.setQuote(split(file));

        return fq;        
    }

    public File quoteToFile(FileQuoted fileQ) {
        File file = new File(fileQ.getName());
        file = merge(fileQ.getQuote(), fileQ.getName());
        return file;
    }

    private Map<QuoteSealed,Object> split(File file) {
            int c = 0;
            //dimensione del chunk
            Long dim = new Long(10000); //size of chunk
            //index = 0;
            Map<QuoteSealed,Object> fileSplitted = new TreeMap<QuoteSealed, Object>(new QuoteSealedComparator());
            Crypt cryptQuote = new Crypt();
            cryptQuote.setPassPhrase("paolo"); //TODO: da sistemare la password per criptare
            //inizio la serializzazione / divisione de file in chunk
            FileInputStream fileStream;
            try {
                    fileStream = new FileInputStream(file);

                    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();

                    long fileSize = file.length();
                    residuo = fileSize;
                    //calcolo il numero di chunk
                    //long quote = (fileSize / 10000);

                    if (file.length() > 10000) {
                        dim = new Long(10000);
                    } else {
                        dim = fileSize;
                    }

                    int element = 0;
                    
                    while((-1 != (c = fileStream.read()))) {
                        byteOut.write(c);

                        if ((byteOut.size() == dim)) {
                            Quote _quote = new Quote();
                            _quote.setObj(byteOut.toByteArray());
                            //prendo il quote, lo cripto e lo inserisco nella map

                            Object sealed = cryptQuote.encrypt(_quote);

                            fileSplitted.put(
                                    new QuoteSealed((element++), sealed),
                                    sealed);
                            byteOut.reset();
                            residuo -= dim;
                            dim = (residuo > 10000) ? 10000 : residuo;
                        }
                    }
 
            } catch (IOException e) {
                    return null;
            }

            return fileSplitted;
    }

    private File merge(Map<QuoteSealed,Object> map, String filename){
        File file = new File(filename);
        FileOutputStream fos;

        Crypt cryptQuote = new Crypt();
        cryptQuote.setPassPhrase("paolo"); //TODO: da sistemare la password per criptare
        Quote _quote = new Quote();

        try {
            fos = new FileOutputStream(file);

            for (Object obj : map.values()){
                _quote = cryptQuote.decrypt((SealedObject)obj);
                fos.write(_quote.getObj());
            }
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }


        return file;
    }


}
